﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
using System.Drawing;

namespace FaceCat
{
    /// <summary>
    /// 滚动按钮
    /// </summary>
    public class ScrollButtonM : FCButton
    {
        public int m_arrowType = 0;

        /// <summary>
        /// 绘图方法
        /// </summary>
        /// <param name="paint"></param>
        /// <param name="clipRect"></param>
        public override void onPaint(FCPaint paint, FCRect clipRect)
        {
            int width = getWidth(), height = getHeight();
            if (width > 0 && height > 0)
            {
                FCRect drawRect = new FCRect(0, 0, width, height);
                if (m_arrowType == 5)
                {
                    if (this == m_native.getPushedView() || this == m_native.getHoveredView())
                    {
                        paint.fillRoundRect(FCColor.rgb(42, 138, 195), drawRect, 4);
                    }
                    else
                    {
                        if (MyColor.m_style == 0)
                        {
                            paint.fillRoundRect(FCColor.rgb(100, 100, 100), drawRect, 4);
                        }
                        else
                        {
                            paint.fillRoundRect(FCColor.rgb(225, 225, 225), drawRect, 4);
                        }
                    }
                }
                else if (m_arrowType == 6)
                {
                    if (this == m_native.getPushedView())
                    {
                        paint.fillRect(FCColor.rgba(0, 0, 0, 25), drawRect);
                    }
                }
                else
                {
                    if (allowDrag() && this == m_native.getPushedView())
                    {
                        paint.fillRect(FCColor.rgb(42, 138, 195), drawRect);
                    }
                    else
                    {
                        if (MyColor.m_style == 0)
                        {
                            paint.fillRect(FCColor.rgb(100, 100, 100), drawRect);
                        }
                        else
                        {
                            paint.fillRect(FCColor.rgb(220, 220, 220), drawRect);
                        }
                    }
                }
                if (this == m_native.getPushedView())
                {
                    int mw = width / 2, mh = height / 2;
                    FCPoint point1 = new FCPoint();
                    FCPoint point2 = new FCPoint();
                    FCPoint point3 = new FCPoint();
                    int ts = 3;
                    switch (m_arrowType)
                    {
                        case 1:
                            point1.x = mw - ts;
                            point1.y = mh;
                            point2.x = mw + ts;
                            point2.y = mh - ts * 3;
                            point3.x = mw + ts;
                            point3.y = mh + ts * 3;
                            break;
                        case 2:
                            point1.x = mw + ts;
                            point1.y = mh;
                            point2.x = mw - ts;
                            point2.y = mh - ts * 3;
                            point3.x = mw - ts;
                            point3.y = mh + ts * 3;
                            break;
                        case 3:
                            point1.x = mw;
                            point1.y = mh - ts;
                            point2.x = mw - ts * 3;
                            point2.y = mh + ts;
                            point3.x = mw + ts * 3;
                            point3.y = mh + ts;
                            break;
                        case 4:
                            point1.x = mw;
                            point1.y = mh + ts;
                            point2.x = mw - ts * 3;
                            point2.y = mh - ts;
                            point3.x = mw + ts * 3;
                            point3.y = mh - ts;
                            break;
                    }
                    FCPoint[] points = new FCPoint[3];
                    points[0] = point1;
                    points[1] = point2;
                    points[2] = point3;
                    paint.fillPolygon(FCColor.rgb(0, 0, 0), points);
                }
            }
        }

        /// <summary>
        /// 绘制边线方法
        /// </summary>
        /// <param name="paint"></param>
        /// <param name="clipRect"></param>
        public override void onPaintBorder(FCPaint paint, FCRect clipRect)
        {
            //base.onPaintBorder(paint, clipRect);
        }
    }

    /// <summary>
    /// 设备对接
    /// </summary>
    public class WPFHost:FCHost
    {
        protected IntPtr m_hImc = IntPtr.Zero;
        [DllImport("user32.dll", ExactSpelling = true)]
        public static extern bool GetUpdateRect(IntPtr hWnd, out FCRect lpRect, bool bErase);
        [DllImport("user32.dll", ExactSpelling = true)]
        public static extern int IntersectRect(ref FCRect lpDestRect, ref FCRect lpSrc1Rect, ref FCRect lpSrc2Rect);
        [DllImport("user32.dll", ExactSpelling = true)]
        public static extern int UnionRect(ref FCRect lpDestRect, ref FCRect lpSrc1Rect, ref FCRect lpSrc2Rect);
        [DllImport("Imm32.dll")]
        public static extern IntPtr ImmGetContext(IntPtr hWnd);
        [DllImport("Imm32.dll")]
        public static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC);
        [DllImport("Imm32.dll")]
        public static extern int ImmGetCompositionString(IntPtr hIMC, int dwIndex, StringBuilder lpBuf, int dwBufLen);
        [DllImport("Imm32.dll")]
        public static extern int ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);
        [DllImport("Imm32.dll")]
        public static extern bool ImmSetCompositionWindow(IntPtr hIMC, ref COMPOSITIONFORM lpCompForm);
        [StructLayout(LayoutKind.Sequential)]
        public struct COMPOSITIONFORM
        {
            public uint dwStyle;
            public System.Windows.Point ptCurrentPos;
            public FCRect rcArea;
        }
        public const int WM_ERASEBKGND = 0x0014;
        public const int WM_PAINT = 0x000F;
        public const int WM_LBUTTONDOWN = 0x0201;
        public const int WM_RBUTTONDOWN = 0x0204;
        public const int WM_LBUTTONDBLCLK = 0x0203;
        public const int WM_RBUTTONDBLCLK = 0x0206;
        public const int WM_LBUTTONUP = 0x0202;
        public const int WM_RBUTTONUP = 0x0205;
        public const int WM_MOUSEMOVE = 0x0200;
        public const int WM_MOUSEWHEEL = 0x020A;
        public const int WM_TIMER = 0x0113;
        public const int WM_IME_SETCONTEXT = 0x0281;
        public const int WM_IME_CHAR = 0x0286;
        public const int WM_CHAR = 0x0102;
        public const int WM_IME_COMPOSITION = 0x010F;
        public const int WM_KEYDOWN = 0x0100;
        public const int WM_SYSKEYDOWN = 0x0104;
        public const int WM_KEYUP = 0x0101;
        public const int WM_SYSKEYUP = 0x0105;
        public const int GCS_COMPSTR = 0x0008;
        public const int HC_ACTION = 0;
        public const int PM_REMOVE = 0x0001;
        public const int WM_INPUTLANGCHANGE = 0x0051;
        public const int WM_INPUTLANGCHANGEREQUEST = 0x0050;
        public const int WM_GETDLGCODE = 0x0087;
        public int GCS_RESULTSTR = 0x0800;
        private delegate void TimerProc(IntPtr hWnd, uint nMsg, int nIDEvent, int dwTime);
        [DllImport("user32")]
        private static extern int SetTimer(IntPtr hWnd, int nIDEvent, int uElapse, TimerProc CB);
        [DllImport("user32")]
        private static extern int KillTimer(IntPtr hWnd, int nIDEvent);
        [DllImport("user32")]
        private static extern int GetKeyState(int nVirtKey);
        [DllImport("user32")]
        private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
        [DllImport("user32")]
        private static extern int PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
        [DllImport("user32")]
        private static extern int UpdateWindow(IntPtr hWnd);
        [DllImport("user32.dll")]
        static extern bool GetWindowRect(IntPtr hWnd, ref FCRect lpRect);

        [DllImport("user32.dll")]
        static extern uint ActivateKeyboardLayout(
                uint hkl,
                uint Flags);


        [DllImport("user32.dll", EntryPoint = "GetCursorPos")]
        public static extern bool GetCursorPos(ref FCPoint lpPoint);

        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern bool ScreenToClient(IntPtr hWnd, ref FCPoint rect);

        /// <summary>
        /// 绘图对象
        /// </summary>
        public FCUIView m_uiView;

        /// <summary>
        /// 是否可以操作
        /// </summary>
        protected bool m_allowOperate = true;

        /// <summary>
        /// 是否支持局部绘图
        /// </summary>
        protected bool m_allowPartialPaint = true;

        /// <summary>
        /// 调用视图线程方法的参数
        /// </summary>
        protected HashMap<int, Object> m_invokeArgs = new HashMap<int, Object>();

        /// <summary>
        /// 调用视图线程方法的视图
        /// </summary>
        protected HashMap<int, FCView> m_invokeViews = new HashMap<int, FCView>();

        /// <summary>
        /// 调用视图线程方法的流水号
        /// </summary>
        protected int m_invokeSerialID = 0;

        /// <summary>
        /// 获取是否允许操作
        /// </summary>
        public override bool allowOperate()
        {
            return m_allowOperate;
        }

        /// <summary>
        /// 获取是否允许局部绘图
        /// </summary>
        public override bool allowPartialpaint()
        {
            return m_allowPartialPaint;
        }

        protected IntPtr m_hWnd;

        /// <summary>
        /// 获取图形视图
        /// </summary>
        public virtual IntPtr getHWnd()
        {
            return m_hWnd;
        }

        /// <summary>
        /// 设置图形视图
        /// </summary>
        /// <param name="value"></param>
        public virtual void setHWnd(IntPtr value)
        {
            m_hWnd = value;
            m_hImc = ImmGetContext(m_hWnd);
        }

        public int m_pInvokeMsgID = 0x0401;

        /// <summary>
        /// 获取调用线程方法的消息ID
        /// </summary>
        public virtual int getPInvokeMsgID()
        {
            return m_pInvokeMsgID;
        }

        /// <summary>
        /// 设置调用线程方法的消息ID
        /// </summary>
        public virtual void setPInvokeMsgID(int value)
        {
            m_pInvokeMsgID = value;
        }

        public bool m_isDeleted;

        /// <summary>
        /// 获取是否已被销毁
        /// </summary>
        public override bool isDeleted()
        {
            return m_isDeleted;
        }

        /// <summary>
        /// 在视图的线程中调用方法
        /// </summary>
        /// <param name="view">视图</param>
        /// <param name="args">参数</param>
        public override void beginInvoke(FCView view, object args)
        {
            int serialID = 0;
            lock (this)
            {
                m_invokeSerialID++;
                serialID = m_invokeSerialID;
            }
            lock (m_invokeArgs)
            {
                m_invokeArgs.put(serialID, args);
            }
            lock (m_invokeViews)
            {
                m_invokeViews.put(serialID, view);
            }
            IntPtr hWnd = m_hWnd;
            SendMessage(hWnd, m_pInvokeMsgID, serialID, 0);
        }

        /// <summary>
        /// 复制文本
        /// </summary>
        /// <param name="text">文本</param>
        public override void copy(string text)
        {
            System.Windows.Forms.Clipboard.SetText(text);
        }

        /// <summary>
        /// 创建内部控件
        /// </summary>
        /// <param name="parent">父控件</param>
        /// <param name="clsid">控件标识</param>
        /// <returns>内部控件</returns>
        public override FCView createInternalView(FCView parent, String clsid)
        {
            switch (clsid)
            {
                case "datetitle":
                    {
                        FCCalendar calendar = parent as FCCalendar;
                        return new DateTitle(calendar);
                    }
                case "headdiv":
                    {
                        FCCalendar calendar = parent as FCCalendar;
                        HeadDiv headDiv = new HeadDiv(calendar);
                        headDiv.setWidth(parent.getWidth());
                        headDiv.setDock(FCDockStyle.Top);
                        return headDiv;
                    }
                case "lastbutton":
                    {
                        FCCalendar calendar = parent as FCCalendar;
                        return new ArrowButton(calendar);
                    }
                case "nextbutton":
                    {
                        FCCalendar calendar = parent as FCCalendar;
                        ArrowButton nextBtn = new ArrowButton(calendar);
                        nextBtn.setToLast(false);
                        return nextBtn;
                    }
                case "splitter":
                    {
                        ScrollButtonM splitter = new ScrollButtonM();
                        splitter.setBackColor(FCColor.rgba(0, 0, 0, 25));
                        splitter.setBorderColor(FCColor.rgba(200, 200, 200, 100));
                        splitter.setSize(new FCSize(5, 5));
                        return splitter;
                    }
                case "addbutton":
                    {
                        FCScrollBar scrollBar = parent as FCScrollBar;
                        scrollBar.setBorderColor(FCColor.None);
                        scrollBar.setBackColor(FCColor.None);
                        RibbonButton addButton = new RibbonButton();
                        addButton.setSize(new FCSize(15, 15));
                        if (scrollBar is FCHScrollBar)
                        {
                            addButton.ArrowType = 2;
                        }
                        else if (scrollBar is FCVScrollBar)
                        {
                            addButton.ArrowType = 4;
                        }
                        if (scrollBar is FCVScrollBar)
                        {
                            addButton.setHeight(0);
                        }
                        else if (scrollBar is FCHScrollBar)
                        {
                            addButton.setWidth(0);
                        }
                        return addButton;
                    }
                case "backbutton":
                    {
                        FCScrollBar scrollBar = parent as FCScrollBar;
                        scrollBar.setBorderColor(FCColor.None);
                        scrollBar.setBackColor(FCColor.None);
                        ScrollButtonM backButton = new ScrollButtonM();
                        backButton.setBorderColor(FCColor.None);
                        backButton.setBackColor(FCColor.None);
                        backButton.m_arrowType = 6;
                        return backButton;
                    }
                case "scrollbutton":
                    {
                        FCScrollBar scrollBar = parent as FCScrollBar;
                        scrollBar.setBorderColor(FCColor.None);
                        scrollBar.setBackColor(FCColor.None);
                        ScrollButtonM scrollButton = new ScrollButtonM();
                        scrollButton.setAllowDrag(true);
                        scrollButton.setBackColor(FCColor.rgba(94, 102, 115, 200));
                        scrollButton.setBorderColor(FCColor.None);
                        scrollButton.setCornerRadius(4);
                        scrollButton.m_arrowType = 5;
                        return scrollButton;
                    }
                case "reducebutton":
                    {
                        FCScrollBar scrollBar = parent as FCScrollBar;
                        scrollBar.setBorderColor(FCColor.None);
                        scrollBar.setBackColor(FCColor.None);
                        RibbonButton reduceButton = new RibbonButton();
                        reduceButton.setSize(new FCSize(15, 15));
                        if (scrollBar is FCHScrollBar)
                        {
                            reduceButton.ArrowType = 1;
                        }
                        else if (scrollBar is FCVScrollBar)
                        {
                            reduceButton.ArrowType = 3;
                        }
                        if (scrollBar is FCVScrollBar)
                        {
                            reduceButton.setHeight(0);
                        }
                        else if (scrollBar is FCHScrollBar)
                        {
                            reduceButton.setWidth(0);
                        }
                        return reduceButton;
                    }
                case "headerbutton":
                    {
                        RibbonButton button = new RibbonButton();
                        button.setAllowDrag(true);
                        FCSize size = new FCSize(100, 20);
                        button.setSize(size);
                        return button;
                    }
                case "dropdownbutton":
                    {
                        FCComboBox comboBox = parent as FCComboBox;
                        if (comboBox != null)
                        {
                            RibbonButton dropDownButton = new RibbonButton();
                            dropDownButton.ArrowType = 4;
                            dropDownButton.setDisplayOffset(false);
                            int width = comboBox.getWidth();
                            int height = comboBox.getHeight();
                            FCPoint location = new FCPoint(width - 20, 0);
                            dropDownButton.setLocation(location);
                            FCSize size = new FCSize(20, height);
                            dropDownButton.setSize(size);
                            return dropDownButton;
                        }
                        //日期选择
                        FCDateTimePicker datePicker = parent as FCDateTimePicker;
                        if (datePicker != null)
                        {
                            RibbonButton dropDownButton = new RibbonButton();
                            dropDownButton.ArrowType = 4;
                            dropDownButton.setDisplayOffset(false);
                            int width = datePicker.getWidth();
                            int height = datePicker.getHeight();
                            FCPoint location = new FCPoint(width - 16, 0);
                            dropDownButton.setLocation(location);
                            FCSize size = new FCSize(16, height);
                            dropDownButton.setSize(size);
                            return dropDownButton;
                        }
                        break;
                    }
                case "dropdownmenu":
                    {
                        //下拉列表
                        FCComboBox comboBox = parent as FCComboBox;
                        if (comboBox != null)
                        {
                            FCComboBoxMenu comboBoxMenu = new FCComboBoxMenu();
                            comboBoxMenu.setComboBox(comboBox);
                            comboBoxMenu.setPopup(true);
                            FCSize size = new FCSize(100, 200);
                            comboBoxMenu.setSize(size);
                            return comboBoxMenu;
                        }
                        //日期选择
                        FCDateTimePicker datePicker = parent as FCDateTimePicker;
                        if (datePicker != null)
                        {
                            FCMenu dropDownMenu = new FCMenu();
                            dropDownMenu.setPadding(new FCPadding(1));
                            dropDownMenu.setPopup(true);
                            FCSize size = new FCSize(200, 200);
                            dropDownMenu.setSize(size);
                            return dropDownMenu;
                        }
                        break;
                    }
                case "downbutton":
                    {
                        FCButton downButton = new FCButton();
                        downButton.setDisplayOffset(false);
                        downButton.setText("-");
                        FCSize size = new FCSize(16, 16);
                        downButton.setSize(size);
                        return downButton;
                    }
                case "upbutton":
                    {
                        FCButton upButton = new FCButton();
                        upButton.setDisplayOffset(false);
                        upButton.setText("+");
                        FCSize size = new FCSize(16, 16);
                        upButton.setSize(size);
                        return upButton;
                    }
                case "hscrollbar":
                    {
                        FCHScrollBar hScrollBar = new FCHScrollBar();
                        hScrollBar.setVisible(false);
                        hScrollBar.setSize(new FCSize(10, 10));
                        return hScrollBar;
                    }
                case "vscrollbar":
                    {
                        FCVScrollBar vScrollBar = new FCVScrollBar();
                        vScrollBar.setVisible(false);
                        vScrollBar.setSize(new FCSize(10, 10));
                        return vScrollBar;
                    }
                case "edittextbox":
                    {
                        FCTextBox textBox = new FCTextBox();
                        textBox.setFont(new FCFont("Default", 14, false, false, false));
                        textBox.setPadding(new FCPadding(0, 0, 0, 0));
                        return textBox;
                    }
            }
            return null;
        }

        /// <summary>
        /// 销毁资源
        /// </summary>
        public override void delete()
        {
            if (!m_isDeleted)
            {
                m_invokeArgs.clear();
                m_invokeViews.clear();
                m_isDeleted = true;
            }
        }

        /// <summary>
        /// 获取光标
        /// </summary>
        /// <returns>光标</returns>
        public override FCCursors getCursor()
        {
            return FCCursors.Arrow;
        }

                /// <summary>
        /// 获取鼠标位置
        /// </summary>
        /// <returns>坐标</returns>
        public FCPoint getMousePoint()
        {
            FCPoint mp = new FCPoint();
            GetCursorPos(ref mp);
            System.Windows.Point clientPoint = m_uiView.PointFromScreen(new System.Windows.Point(mp.x, mp.y));
            mp.x = (int)clientPoint.X;
            mp.y = (int)clientPoint.Y;
            return mp;
        }

        /// <summary>
        /// 获取矩形相交区
        /// </summary>
        /// <param name="lpDestRect">相交矩形</param>
        /// <param name="lpSrc1Rect">矩形1</param>
        /// <param name="lpSrc2Rect">矩形2</param>
        /// <returns>是否相交</returns>
        public override int getIntersectRect(ref FCRect lpDestRect, ref FCRect lpSrc1Rect, ref FCRect lpSrc2Rect)
        {
            lpDestRect.left = Math.Max(lpSrc1Rect.left, lpSrc2Rect.left);
            lpDestRect.right = Math.Min(lpSrc1Rect.right, lpSrc2Rect.right);
            lpDestRect.top = Math.Max(lpSrc1Rect.top, lpSrc2Rect.top);
            lpDestRect.bottom = Math.Min(lpSrc1Rect.bottom, lpSrc2Rect.bottom);
            if (lpDestRect.right > lpDestRect.left && lpDestRect.bottom > lpDestRect.top)
            {
                return 1;
            }
            else
            {
                lpDestRect.left = 0;
                lpDestRect.right = 0;
                lpDestRect.top = 0;
                lpDestRect.bottom = 0;
                return 0;
            }
        }

        protected FCNative m_native;

        /// <summary>
        /// 获取方法库
        /// </summary>
        public override FCNative getNative()
        {
            return m_native;
        }

        /// <summary>
        /// 获取尺寸
        /// </summary>
        /// <returns>大小</returns>
        public override FCSize getSize()
        {
            return new FCSize(m_native.getSize().cx, m_native.getSize().cy);
        }

        /// <summary>
        /// 触摸位置
        /// </summary>
        public FCPoint m_touchPoint = new FCPoint();

        /// <summary>
        /// 获取触摸位置
        /// </summary>
        /// <returns>坐标</returns>
        public override FCPoint getTouchPoint()
        {
            return m_touchPoint;
        }

        /// <summary>
        /// 获取矩形并集区
        /// </summary>
        /// <param name="lpDestRect">并集矩形</param>
        /// <param name="lpSrc1Rect">矩形1</param>
        /// <param name="lpSrc2Rect">矩形2</param>
        /// <returns>是否相交</returns>
        public override int getUnionRect(ref FCRect lpDestRect, ref FCRect lpSrc1Rect, ref FCRect lpSrc2Rect)
        {
            return UnionRect(ref lpDestRect, ref lpSrc1Rect, ref lpSrc2Rect);
        }

        /// <summary>
        /// 刷新绘图
        /// </summary>
        public override void invalidate()
        {
            if (m_uiView != null)
            {
                m_uiView.invalidate(new FCRect(0, 0, m_native.getSize().cx, m_native.getSize().cy));
            }
        }

        /// <summary>
        /// 刷新绘图
        /// </summary>
        /// <param name="rect">区域</param>
        public override void invalidate(FCRect rect)
        {
            if (m_uiView != null)
            {
                m_uiView.invalidate(rect);
            }
        }

        /// <summary>
        /// 在视图的线程中调用方法
        /// </summary>
        /// <param name="view">视图</param>
        /// <param name="args">参数</param>
        public override void invoke(FCView view, object args)
        {
            int serialID = 0;
            lock (this)
            {
                m_invokeSerialID++;
                serialID = m_invokeSerialID;
            }
            lock (m_invokeArgs)
            {
                m_invokeArgs.put(serialID, args);
            }
            lock (m_invokeViews)
            {
                m_invokeViews.put(serialID, view);
            }
            IntPtr hWnd = m_hWnd;
            PostMessage(hWnd, m_pInvokeMsgID, serialID, 0);
        }

        /// <summary>
        /// 获取按键的状态
        /// </summary>
        /// <param name="key">按键</param>
        /// <returns>状态</returns>
        public override bool isKeyPress(int key)
        {
            int state = GetKeyState(key) & 0x8000;
            if (state > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 调用视图线程的方法
        /// </summary>
        /// <param name="invokeSerialID">消息ID</param>
        public virtual void onInvoke(int invokeSerialID)
        {
            Object args = null;
            FCView view = null;
            lock (m_invokeArgs)
            {
                if (m_invokeArgs.containsKey(invokeSerialID))
                {
                    args = m_invokeArgs.get(invokeSerialID);
                    m_invokeArgs.remove(invokeSerialID);
                }
            }
            lock (m_invokeViews)
            {
                if (m_invokeViews.containsKey(invokeSerialID))
                {
                    view = m_invokeViews.get(invokeSerialID);
                    m_invokeViews.remove(invokeSerialID);
                }
            }
            if (view != null)
            {
                view.onInvoke(args);
            }
        }

        /// <summary>
        /// 获取粘贴文本
        /// </summary>
        /// <returns>文本</returns>
        public override string paste()
        {
            String pasteText = System.Windows.Forms.Clipboard.GetText();
            if (pasteText != null)
            {
                return pasteText;
            }
            else
            {
                return "";
            }
        }

        /// <summary>
        /// 设置是否允许操作
        /// </summary>
        public override void setAllowOperate(bool value)
        {
            m_allowOperate = value;
        }

        /// <summary>
        /// 设置是否允许局部绘图
        /// </summary>
        public override void setAllowPartialPaint(bool value)
        {
            m_allowPartialPaint = value;
        }

        /// <summary>
        /// 设置光标
        /// </summary>
        /// <param name="cursor">光标</param>
        public override void setCursor(FCCursors cursor)
        {
        }

        /// <summary>
        /// 设置方法库
        /// </summary>
        public override void setNative(FCNative value)
        {
            m_native = value;
        }

        /// <summary>
        /// 设置触摸位置
        /// </summary>
        public override void setTouchPoint(FCPoint point)
        {
            m_touchPoint = point;
        }

        /// <summary>
        /// 显示提示框
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="mp">位置</param>
        public override void showToolTip(string text, FCPoint mp)
        {
        }

        /// <summary>
        /// 开启秒表
        /// </summary>
        /// <param name="timerID">秒表ID</param>
        /// <param name="interval">间隔</param>
        public override void startTimer(int timerID, int interval)
        {
            IntPtr hWnd = m_hWnd;
            SetTimer(hWnd, timerID, interval, null);
        }

        /// <summary>
        /// 停止秒表
        /// </summary>
        /// <param name="timerID">秒表ID</param>
        public override void stopTimer(int timerID)
        {
            IntPtr hWnd = m_hWnd;
            KillTimer(hWnd, timerID);
        }

        /// <summary>
        /// 消息处理
        /// </summary>
        /// <param name="m">消息</param>
        /// <returns>是否处理</returns>
        public virtual int onMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
        {
            if (m_native != null)
            {
                if (msg == WM_IME_SETCONTEXT && wParam.ToInt32() == 1)
                {
                    ImmAssociateContext(m_hWnd, m_hImc);
                }
                if (msg == m_pInvokeMsgID)
                {
                    onInvoke(wParam.ToInt32());
                }
                switch (msg)
                {
                    case WM_CHAR:
                        {
                            if (m_allowOperate)
                            {
                                KeyEventArgs e = new KeyEventArgs(((Keys)((int)((long)wParam))) | Control.ModifierKeys);
                                char key = (char)e.KeyData;
                                if (m_native.onChar(key))
                                {
                                    return 1;
                                }
                            }
                            break;
                        }
                    case WM_IME_COMPOSITION:
                        {
                            IntPtr hIMC = ImmGetContext(m_hWnd);
                            if (hIMC != IntPtr.Zero)
                            {
                                COMPOSITIONFORM cf = new COMPOSITIONFORM();
                                cf.dwStyle = 0x0002;
                                int ptX = 0, ptY = 0;
                                FCView fView = m_native.getFocusedView();
                                if (fView != null && fView is FCTextBox)
                                {
                                    FCTextBox textBox = fView as FCTextBox;
                                    FCPoint nativePoint = fView.pointToNative(textBox.getCursorPoint());
                                    ptX = nativePoint.x + 1;
                                    ptY = nativePoint.y;
                                    FCPaint paint = m_native.getPaint();
                                    double scaleFactorX = 1, scaleFactorY = 1;
                                    paint.getScaleFactor(ref scaleFactorX, ref scaleFactorY);
                                    ptX = (int)(ptX * scaleFactorX);
                                    ptY = (int)(ptY * scaleFactorY);
                                }
                                cf.ptCurrentPos.X = ptX;
                                cf.ptCurrentPos.Y = ptY;
                                bool setcom = ImmSetCompositionWindow(hIMC, ref cf);
                                ImmReleaseContext(m_hWnd, hIMC);
                            }
                            break;
                        }
                    case WM_KEYDOWN:
                    case WM_SYSKEYDOWN:
                        {
                            if (m_allowOperate)
                            {
                                KeyEventArgs e = new KeyEventArgs(((Keys)((int)((long)wParam))) | Control.ModifierKeys);
                                char key = (char)e.KeyCode;
                                bool handle = m_native.onPreviewsKeyEvent("onkeydown", key);
                                if (handle)
                                {
                                    return 1;
                                }
                                else
                                {
                                    m_native.onKeyDown(key);
                                }
                            }
                            break;
                        }
                    case WM_KEYUP:
                    case WM_SYSKEYUP:
                        {
                            if (m_allowOperate)
                            {
                                KeyEventArgs e = new KeyEventArgs(((Keys)((int)((long)wParam))) | Control.ModifierKeys);
                                char key = (char)e.KeyCode;
                                m_native.onKeyUp(key);
                            }
                            break;
                        }
                    case WM_IME_CHAR:
                        {
                            if (m_allowOperate)
                            {
                                if (wParam.ToInt32() == PM_REMOVE)
                                {
                                    FCView view = m_native.getFocusedView();
                                    if (view != null)
                                    {
                                        StringBuilder str = new StringBuilder();
                                        int size = ImmGetCompositionString(m_hImc, GCS_COMPSTR, null, 0);
                                        size += sizeof(Char);
                                        ImmGetCompositionString(m_hImc, GCS_RESULTSTR, str, size);
                                    }
                                }
                            }
                            break;
                        }
                    case WM_TIMER:
                        {
                            if (hWnd == m_hWnd)
                            {
                                int timerID = (int)wParam;
                                m_native.onTimer(timerID);
                            }
                            break;
                        }
                    case WM_LBUTTONDBLCLK:
                        {
                            m_touchPoint = getMousePoint();
                            if (m_allowOperate)
                            {
                                FCTouchInfo newTouchInfo = new FCTouchInfo();
                                newTouchInfo.m_firstTouch = true;
                                newTouchInfo.m_clicks = 2;
                                m_native.onMouseDown(newTouchInfo);
                                m_native.onMouseUp(newTouchInfo);
                                m_native.onDoubleClick(newTouchInfo);
                            }
                            break;
                        }
                    case WM_LBUTTONDOWN:
                        {
                            m_touchPoint = getMousePoint();
                            if (m_allowOperate)
                            {
                                FCTouchInfo newTouchInfo = new FCTouchInfo();
                                newTouchInfo.m_firstTouch = true;
                                newTouchInfo.m_clicks = 1;
                                m_native.onMouseDown(newTouchInfo);
                            }
                            break;
                        }

                    case WM_LBUTTONUP:
                        {
                            m_touchPoint = getMousePoint();
                            if (m_allowOperate)
                            {
                                FCTouchInfo newTouchInfo = new FCTouchInfo();
                                newTouchInfo.m_firstTouch = true;
                                newTouchInfo.m_clicks = 1;
                                m_native.onMouseUp(newTouchInfo);
                            }
                            break;
                        }
                    case WM_MOUSEMOVE:
                        {
                            m_touchPoint = getMousePoint();
                            if (m_allowOperate)
                            {
                                if ((int)wParam == 1)
                                {
                                    FCTouchInfo newTouchInfo = new FCTouchInfo();
                                    newTouchInfo.m_firstTouch = true;
                                    newTouchInfo.m_clicks = 1;
                                    m_native.onMouseMove(newTouchInfo);
                                }
                                else if ((int)wParam == 2)
                                {
                                    FCTouchInfo newTouchInfo = new FCTouchInfo();
                                    newTouchInfo.m_secondTouch = true;
                                    newTouchInfo.m_clicks = 1;
                                    m_native.onMouseMove(newTouchInfo);
                                }
                                else
                                {
                                    FCTouchInfo newTouchInfo = new FCTouchInfo();
                                    m_native.onMouseMove(newTouchInfo);
                                }
                            }
                            break;
                        }
                    case WM_MOUSEWHEEL:
                        {
                            m_touchPoint = getMousePoint();
                            if (m_allowOperate)
                            {
                                FCTouchInfo newTouchInfo = new FCTouchInfo();
                                newTouchInfo.m_delta = (IntPtr.Size == 8) ? (int)((long)wParam << 32 >> 32) : (int)wParam;
                                m_native.onMouseWheel(newTouchInfo);
                            }
                            break;
                        }
                    case WM_RBUTTONDBLCLK:
                        {
                            m_touchPoint = getMousePoint();
                            if (m_allowOperate)
                            {
                                FCTouchInfo newTouchInfo = new FCTouchInfo();
                                newTouchInfo.m_secondTouch = true;
                                newTouchInfo.m_clicks = 2;
                                m_native.onMouseDown(newTouchInfo);
                                m_native.onMouseUp(newTouchInfo);
                                m_native.onDoubleClick(newTouchInfo);
                            }
                            break;
                        }
                    case WM_RBUTTONDOWN:
                        {
                            m_touchPoint = getMousePoint();
                            if (m_allowOperate)
                            {
                                FCTouchInfo newTouchInfo = new FCTouchInfo();
                                newTouchInfo.m_secondTouch = true;
                                newTouchInfo.m_clicks = 1;
                                m_native.onMouseDown(newTouchInfo);
                            }
                            break;
                        }
                    case WM_RBUTTONUP:
                        {
                            m_touchPoint = getMousePoint();
                            if (m_allowOperate)
                            {
                                FCTouchInfo newTouchInfo = new FCTouchInfo();
                                newTouchInfo.m_secondTouch = true;
                                newTouchInfo.m_clicks = 1;
                                m_native.onMouseUp(newTouchInfo);
                            }
                            break;
                        }
                }
            }
            return 0;
        }

        /// <summary>
        /// 重绘方法
        /// </summary>
        /// <param name="clipRect">裁剪区域</param>
        public virtual void onPaint(FCRect clipRect)
        {
            lock (this)
            {
                FCSize displaySize = m_native.getSize();
                FCSize clientSize = getSize();
                if (displaySize.cx > 0 && displaySize.cy > 0 && clientSize.cx > 0 && clientSize.cy > 0)
                {
                    double scaleFactorX = 1, scaleFactorY = 1;
                    if (m_native.allowScaleSize())
                    {
                        if (clientSize.cx > 0 && clientSize.cy > 0)
                        {
                            FCSize scaleSize = m_native.getScaleSize();
                            scaleFactorX = (double)(clientSize.cx) / scaleSize.cx;
                            scaleFactorY = (double)(clientSize.cy) / scaleSize.cy;
                        }
                    }
                    m_native.getPaint().setScaleFactor(scaleFactorX, scaleFactorY);
                    if (clipRect.left < 0)
                    {
                        clipRect.left = 0;
                    }
                    if (clipRect.top < 0)
                    {
                        clipRect.top = 0;
                    }
                    if (clipRect.right * scaleFactorX > clientSize.cx)
                    {
                        clipRect.right = (int)(clientSize.cx / scaleFactorX);
                    }
                    if (clipRect.bottom * scaleFactorY > clientSize.cy)
                    {
                        clipRect.bottom = (int)(clientSize.cy / scaleFactorY);
                    }
                    if (clipRect.bottom < 0)
                    {
                        clipRect.bottom = 0;
                    }
                    if (clipRect.right < 0)
                    {
                        clipRect.right = 0;
                    }
                    System.Drawing.Graphics g = Graphics.FromHwnd(m_hWnd);
                    m_native.getPaint().beginPaint(g.GetHdc(), new FCRect(0, 0, clientSize.cx, clientSize.cy), clipRect);
                    m_native.onPaint(clipRect);
                    //m_native.getPaint().fillRect(FCColor.rgba(0, 0, 0, 100), new FCRect(0, 0, clientSize.cx, clientSize.cy));
                    m_native.getPaint().endPaint();
                    g.Dispose();
                }
            }
        }
    }
}
